﻿
using System;
using System.Collections.Generic;
#if TWEENSYSTEM_ENABLE_TEXTMESHPRO
using TMPro;
#endif 
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI; 

namespace XFGameFramework.TweenSystem
{

    [Serializable]
    public class AnimationFloatEvent : UnityEvent<float> {}

    [Serializable]
    public class AnimationBoolEvent : UnityEvent<bool> { }

    public enum TransformTweenType 
    {
        [Tooltip("Position")]
        Position,
        [Tooltip("LocalPosition")]
        LocalPosition,
        [Tooltip("EulerAngles")]
        EulerAngles,
        [Tooltip("LocalEulerAngles")]
        LocalEulerAngles,
        [Tooltip("Rotation")]
        Rotation,
        [Tooltip("LocalRotation")]
        LocalRotation,
        [Tooltip("LocalScale")]
        LocalScale
    }
    public enum SpriteRendererTweenType 
    {
        [Tooltip("Color")]
        Color,
        [Tooltip("Fade")]
        Fade,
        [Tooltip("Size")]
        Size
    }
    public enum SliderTweenType 
    {
        [Tooltip("Value")]
        Value,
        [Tooltip("NormalizedValue")]
        NormalizedValue
    }
    public enum ScrollRectTweenType 
    {
        [Tooltip("HorizontalNormalizedPosition")]
        HorizontalNormalizedPosition,
        [Tooltip("VerticalNormalizedPosition")]
        VerticalNormalizedPosition,
        [Tooltip("NormalizedPosition")]
        NormalizedPosition
    }
    public enum RectTransfromTweenType 
    {
        [Tooltip("AnchoredPosition")]
        AnchoredPosition,
        [Tooltip("AnchoredPosition3D")]
        AnchoredPosition3D,
        [Tooltip("AnchorMin")]
        AnchorMin,
        [Tooltip("AnchorMax")]
        AnchorMax,
        [Tooltip("OffsetMin")]
        OffsetMin,
        [Tooltip("OffsetMax")]
        OffsetMax,
        [Tooltip("Pivot")]
        Pivot,
        [Tooltip("SizeDelta")]
        SizeDelta
    }

    public enum ImageTweenType
    {
        [Tooltip("FillAmount")]
        FillAmount,
        [Tooltip("Color")]
        Color,
        [Tooltip("Fade")]
        Fade
    }

    public enum GraphicTweenType 
    {
        [Tooltip("Color")]
        Color,
        [Tooltip("Fade")]
        Fade
    }

    public enum CanvasGroupTweenType 
    {
        [Tooltip("Fade")]
        Fade
    }

    public enum AnimatorTweenType 
    {
        [Tooltip("层级权重")]
        LayerWeight
    }

    public enum TextTweenType 
    {
        [Tooltip("文本")]
        Text,
        [Tooltip("Color")]
        Color,
        [Tooltip("Fade")]
        Fade
    }


    public enum ComponentType
    {
        [Tooltip("Transform")]
        Transform,
        [Tooltip("SpriteRenderer")]
        SpriteRenderer,
        [Tooltip("Slider")]
        Slider,
        [Tooltip("ScrollRect")]
        ScrollRect,
        [Tooltip("RectTransfrom")]
        RectTransfrom,
        [Tooltip("Image")]
        Image,
        [Tooltip("Graphic,UI的基类,如果需要控制Image或Text等组件的颜色和透明度可以选择该类型!")]
        Graphic,
        [Tooltip("CanvasGroup")]
        CanvasGroup,

        Text,
        TextMesh,
#if TWEENSYSTEM_ENABLE_TEXTMESHPRO
        TextMeshPro = 10,
        TextMeshProUGUI = 11,
#endif

        Animator = 12

        // 后面加新的类型，一定要指定一下数字，否则可能会因为是否启用TextMeshPro而导致值发生变化

    }
     
    /// <summary>
    /// 动画数据
    /// </summary>
    [Serializable]
    public class AnimationData 
    {
        #region 字段
        /// <summary>
        /// 目标游戏物体
        /// </summary>
        [Tooltip("目标游戏物体")]
        public GameObject target;
        /// <summary>
        /// 要渐变的目标组件类型
        /// </summary>
        [Tooltip("要渐变的目标组件类型")]
        public ComponentType componentType;
        /// <summary>
        /// transform组件渐变类型(componentType为Transform时有效)
        /// </summary>
        [Tooltip("transform组件渐变类型(componentType为Transform时有效)")]
        public TransformTweenType transformTweenType;
        /// <summary>
        /// SpriteRenderer组件渐变类型(componentType为SpriteRenderer时有效)
        /// </summary>
        [Tooltip("SpriteRenderer组件渐变类型(componentType为SpriteRenderer时有效)")]
        public SpriteRendererTweenType spriteRendererTweenType;
        /// <summary>
        /// Slider组件渐变类型(componentType为Slider时有效)
        /// </summary>
        [Tooltip("Slider组件渐变类型(componentType为Slider时有效)")]
        public SliderTweenType sliderTweenType;
        /// <summary>
        /// ScrollRect组件渐变类型(componentType为ScrollRect时有效)
        /// </summary>
        [Tooltip("ScrollRect组件渐变类型(componentType为ScrollRect时有效)")]
        public ScrollRectTweenType scrollRectTweenType;
        /// <summary>
        /// RectTransfrom组件渐变类型(componentType为RectTransfrom时有效)
        /// </summary>
        [Tooltip("RectTransfrom组件渐变类型(componentType为RectTransfrom时有效)")]
        public RectTransfromTweenType rectTransfromTweenType;
        /// <summary>
        ///  Image组件渐变类型(componentType为Image时有效)
        /// </summary>
        [Tooltip("Image组件渐变类型(componentType为Image时有效)")]
        public ImageTweenType imageTweenType;
        /// <summary>
        /// Graphic组件渐变类型(componentType为Graphic时有效)
        /// </summary>
        [Tooltip("Graphic组件渐变类型(componentType为Graphic时有效)")]
        public GraphicTweenType graphicTweenType;
        /// <summary>
        /// CanvasGroup组件渐变类型(componentType为CanvasGroup时有效)
        /// </summary>
        [Tooltip("CanvasGroup组件渐变类型(componentType为CanvasGroup时有效)")]
        public CanvasGroupTweenType canvasGroupTweenType;
        /// <summary>
        /// Animator组件渐变类型(componentType为Animator时有效)
        /// </summary>
        [Tooltip("Animator组件渐变类型(componentType为Animator时有效)")]
        public AnimatorTweenType animatorTweenType;
        /// <summary>
        /// Text组件渐变类型(componentType为Text时有效)
        /// </summary>
        [Tooltip("Text组件渐变类型(componentType为Text时有效)")]
        public TextTweenType textTweenType;

        /// <summary>
        /// 缓动曲线
        /// </summary>
        [Tooltip("缓动曲线")]
        public Ease ease;

        /// <summary>
        /// 自定义缓动曲线
        /// </summary>
        [Tooltip("自定义缓动曲线")]
        public AnimationCurve curve;

        /// <summary>
        /// float类型的起始值
        /// </summary>
        [Tooltip("float类型的起始值")]
        public float float_from;
        /// <summary>
        /// float类型的目标值
        /// </summary>
        [Tooltip("float类型的目标值")]
        public float float_to;

        /// <summary>
        /// vector2类型的起始值
        /// </summary>
        [Tooltip("vector2类型的起始值")]
        public Vector2 vector2_from;

        /// <summary>
        /// vector2类型的目标值
        /// </summary>
        [Tooltip("vector2类型的目标值")]
        public Vector2 vector2_to;

        /// <summary>
        /// vector3类型的起始值
        /// </summary>
        [Tooltip("vector3类型的起始值")]
        public Vector3 vector3_from;

        /// <summary>
        /// vector3类型的目标值
        /// </summary>
        [Tooltip("vector3类型的目标值")]
        public Vector3 vector3_to;

        /// <summary>
        /// Quaternion类型的起始值
        /// </summary>
        [Tooltip("Quaternion类型的起始值")]
        public Quaternion quaternion_from;

        /// <summary>
        /// Quaternion类型的目标值
        /// </summary>
        [Tooltip("Quaternion类型的目标值")]
        public Quaternion quaternion_to;

        /// <summary>
        /// Color类型的起始值
        /// </summary>
        [Tooltip("Color类型的起始值")]
        public Color color_from = Color.white;

        /// <summary>
        /// Color类型的目标值
        /// </summary>
        [Tooltip("Color类型的目标值")]
        public Color color_to = Color.white;

        /// <summary>
        /// 层级名称(渐变Animator时有效)
        /// </summary>
        [Tooltip("层级名称(渐变Animator时有效)")]
        public string layerName;

        /// <summary>
        /// string目标值(渐变文本时有效)
        /// </summary>
        [Tooltip("string目标值(渐变文本时有效)")]
        public string str_value;

        /// <summary>
        /// 延迟时间
        /// </summary>
        [Tooltip("延迟时间")]
        public float delay;

        /// <summary>
        /// 持续时间
        /// </summary>
        [Tooltip("持续时间")]
        public float duration;

        /// <summary>
        /// 循环模式
        /// </summary>
        [Tooltip("循环模式")]
        public LoopMode loopMode;

        /// <summary>
        /// 循环次数(小于等于0 表示一直循环)
        /// </summary>
        public int loopCount = -1;


        public float currentProgress;

        #endregion

        #region 属性

        /// <summary>
        /// 渐变动画实例
        /// </summary>
        internal Tweener tweener { get;private set; }

        #endregion

        #region 事件

        [Header("进度改变事件")]
        public AnimationFloatEvent onProgress;

        [Header("完成事件")]
        public UnityEvent onComplete;

        [Header("中断事件")]
        public UnityEvent onKill;

        #endregion

        #region 方法
         
        private void OnTween(Tweener t) 
        {
            onProgress?.Invoke(t.progress); 
        }

        private void OnComplete(Tweener t) {
            onComplete?.Invoke(); 
        }

        private void OnKill(Tweener t) 
        {
            onKill?.Invoke();
        }

        #endregion


        #region Tweener

        internal void HandleAnimationData( bool inverse = false, bool fromCurrentProgress = false, bool ingoreTimeScale = true)
        {
            if (target == null)
                return;

            

            switch ( componentType)
            {
                case ComponentType.Transform:
                    HandleAnimationTransform(  inverse, fromCurrentProgress, ingoreTimeScale);
                    break;
                case ComponentType.SpriteRenderer:
                    HandleAnimationSpriteRenderer(  inverse, fromCurrentProgress, ingoreTimeScale);
                    break;
                case ComponentType.Slider:
                    HandleAnimationSlider(  inverse, fromCurrentProgress, ingoreTimeScale);
                    break;
                case ComponentType.ScrollRect:
                    HandleAnimationScrollRect(  inverse, fromCurrentProgress, ingoreTimeScale);
                    break;
                case ComponentType.RectTransfrom:
                    HandleAnimationRectTransfrom( inverse, fromCurrentProgress, ingoreTimeScale);
                    break;
                case ComponentType.Image:
                    HandleAnimationImage(  inverse, fromCurrentProgress, ingoreTimeScale);
                    break;
                case ComponentType.Graphic:
                    HandleAnimationGraphic(  inverse, fromCurrentProgress, ingoreTimeScale);
                    break;
                case ComponentType.CanvasGroup:
                    HandleAnimationCanvasGroup(  inverse, fromCurrentProgress, ingoreTimeScale);
                    break;

                case ComponentType.Animator:
                    HandleAnimationAnimator( inverse, fromCurrentProgress, ingoreTimeScale);
                    break;

                case ComponentType.Text:
                    HandleAnimationText(  inverse, fromCurrentProgress, ingoreTimeScale);
                    break;

                case ComponentType.TextMesh:
                    HandleAnimationTextMesh(  inverse, fromCurrentProgress, ingoreTimeScale);
                    break;
#if TWEENSYSTEM_ENABLE_TEXTMESHPRO
                case ComponentType.TextMeshPro:
                    HandleAnimationTextMeshPro( inverse, fromCurrentProgress, ingoreTimeScale);
                    break;

                case ComponentType.TextMeshProUGUI:
                    HandleAnimationTextMeshProUGUI( inverse, fromCurrentProgress, ingoreTimeScale);
                    break;
#endif

            }

            if (tweener != null) 
            { 
                tweener.Duration = duration;
                tweener.LoopMode = loopMode;
                tweener.Ease = ease;
                tweener.Curve = curve;
                tweener.IgnoreTimeScale = ingoreTimeScale;
                tweener.Delay = delay;
                tweener.LoopCount = loopCount;
            } 

        }

        private  void HandleAnimationTransform(  bool inverse = false, bool fromCurrentProgress = false, bool ingoreTimeScale = true)
        {
            
            //float progress = 0;

            switch ( transformTweenType)
            {
                case TransformTweenType.Position:
                     
                    TweenerCore<Vector3> t_position = InitTweenerVector3(target.transform, TransformExtensions.OnTweenPosition);

                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector3Extensions.InverseLerp( vector3_to, vector3_from, target.transform.position);

                        //tweener = TweenManager.ComponentTween( target.transform,  vector3_to,  vector3_from,duration,loopMode, ease, curve, ingoreTimeScale, TransformExtensions.OnTweenPosition,  delay, progress, loopCount);

                        t_position.From = vector3_to;
                        t_position.To = vector3_from; 
                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector3Extensions.InverseLerp(vector3_from, vector3_to, target.transform.position);

                        //tweener = TweenManager.ComponentTween(target.transform, vector3_from, vector3_to, duration, loopMode, ease, curve, ingoreTimeScale, TransformExtensions.OnTweenPosition, delay, progress, loopCount);
                        t_position.From = vector3_from;
                        t_position.To = vector3_to;
                    }
                    break;
                case TransformTweenType.LocalPosition:

                    TweenerCore<Vector3> t_local_position = InitTweenerVector3(target.transform, TransformExtensions.OnTweenLocalPosition);
                    
                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector3Extensions.InverseLerp(vector3_to, vector3_from, target.transform.localPosition);

                        //tweener = TweenManager.ComponentTween(target.transform, vector3_to, vector3_from, duration, loopMode, ease, curve, ingoreTimeScale, TransformExtensions.OnTweenLocalPosition, delay, progress, loopCount);
                        t_local_position.From = vector3_to;
                        t_local_position.To = vector3_from;
                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector3Extensions.InverseLerp(vector3_from, vector3_to, target.transform.localPosition);

                        //tweener = TweenManager.ComponentTween(target.transform, vector3_from, vector3_to, duration, loopMode, ease, curve, ingoreTimeScale, TransformExtensions.OnTweenLocalPosition, delay, progress, loopCount);
                        t_local_position.From = vector3_from;
                        t_local_position.To = vector3_to;
                    }

                    break;
                case TransformTweenType.EulerAngles:

                    TweenerCore<Vector3> t_euler_angles = InitTweenerVector3(target.transform, TransformExtensions.OnTweenEulerAngles);

                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector3Extensions.InverseLerp(vector3_to, vector3_from, target.transform.eulerAngles);

                        //tweener = TweenManager.ComponentTween(target.transform, vector3_to, vector3_from, duration, loopMode, ease, curve, ingoreTimeScale, TransformExtensions.OnTweenEulerAngles, delay, progress, loopCount);
                        t_euler_angles.From = vector3_to;
                        t_euler_angles.To = vector3_from;
                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector3Extensions.InverseLerp(vector3_from, vector3_to, target.transform.eulerAngles);

                        //tweener = TweenManager.ComponentTween(target.transform, vector3_from, vector3_to, duration, loopMode, ease, curve, ingoreTimeScale, TransformExtensions.OnTweenEulerAngles, delay, progress, loopCount);
                        t_euler_angles.From = vector3_from;
                        t_euler_angles.To = vector3_to;
                    }

                    break;
                case TransformTweenType.LocalEulerAngles:

                    TweenerCore<Vector3> t_local_euler_angles = InitTweenerVector3(target.transform, TransformExtensions.OnTweenLocalEulerAngles);

                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector3Extensions.InverseLerp(vector3_to, vector3_from, target.transform.localEulerAngles);
                        //tweener = TweenManager.ComponentTween(target.transform, vector3_to, vector3_from, duration, loopMode, ease, curve, ingoreTimeScale, TransformExtensions.OnTweenLocalEulerAngles, delay, progress, loopCount);
                        t_local_euler_angles.From = vector3_to;
                        t_local_euler_angles.To = vector3_from;
                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector3Extensions.InverseLerp(vector3_from, vector3_to, target.transform.localEulerAngles);

                        //tweener = TweenManager.ComponentTween(target.transform, vector3_from, vector3_to, duration, loopMode, ease, curve, ingoreTimeScale, TransformExtensions.OnTweenLocalEulerAngles, delay, progress, loopCount);

                        t_local_euler_angles.From = vector3_from;
                        t_local_euler_angles.To = vector3_to;
                    }

                    break;
                case TransformTweenType.Rotation:

                    TweenerCore<Quaternion> t_rotaion = InitTweenerQuaternion(target.transform, TransformExtensions.OnTweenRotation);

                    quaternion_from = Quaternion.Euler(vector3_from);
                    quaternion_to = Quaternion.Euler(vector3_to);

                    if (inverse)
                    {


                        if (fromCurrentProgress)
                            currentProgress = QuaternionExtensions.InverseLerp(quaternion_to, quaternion_from, target.transform.rotation);

                        //tweener = TweenManager.ComponentTween(target.transform, quaternion_to, quaternion_from, duration, loopMode, ease, curve, ingoreTimeScale, TransformExtensions.OnTweenRotation, delay, progress, loopCount);
                        t_rotaion.From = quaternion_to;
                        t_rotaion.To = quaternion_from;
                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = QuaternionExtensions.InverseLerp(quaternion_from, quaternion_to, target.transform.rotation);

                        //tweener = TweenManager.ComponentTween(target.transform, quaternion_from, quaternion_to, duration, loopMode, ease, curve, ingoreTimeScale, TransformExtensions.OnTweenRotation, delay, progress, loopCount);
                        t_rotaion.From = quaternion_from;
                        t_rotaion.To = quaternion_to;
                    }

                    break;
                case TransformTweenType.LocalRotation:

                    TweenerCore<Quaternion> t_local_rotaion = InitTweenerQuaternion(target.transform, TransformExtensions.OnTweenLocalRotation);

                    quaternion_from = Quaternion.Euler(vector3_from);
                    quaternion_to = Quaternion.Euler(vector3_to);

                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = QuaternionExtensions.InverseLerp(quaternion_to, quaternion_from, target.transform.localRotation);

                        //tweener = TweenManager.ComponentTween(target.transform, quaternion_to, quaternion_from, duration, loopMode, ease, curve, ingoreTimeScale, TransformExtensions.OnTweenLocalRotation, delay, progress, loopCount);
                        t_local_rotaion.From = quaternion_to;
                        t_local_rotaion.To = quaternion_from;
                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = QuaternionExtensions.InverseLerp(quaternion_from, quaternion_to, target.transform.localRotation);

                        //tweener = TweenManager.ComponentTween(target.transform, quaternion_from, quaternion_to, duration, loopMode, ease, curve, ingoreTimeScale, TransformExtensions.OnTweenLocalRotation, delay, progress, loopCount);

                        t_local_rotaion.From = quaternion_from;
                        t_local_rotaion.To = quaternion_to;

                    }
                    break;
                case TransformTweenType.LocalScale:

                    TweenerCore<Vector3> t_local_scale = InitTweenerVector3(target.transform, TransformExtensions.OnTweenLocalScale);

                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector3Extensions.InverseLerp(vector3_to, vector3_from, target.transform.localScale);

                        //tweener = TweenManager.ComponentTween(target.transform, vector3_to, vector3_from, duration, loopMode, ease, curve, ingoreTimeScale, TransformExtensions.OnTweenLocalScale, delay, progress, loopCount);
                        t_local_scale.From = vector3_to;
                        t_local_scale.To = vector3_from;
                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector3Extensions.InverseLerp(vector3_from, vector3_to, target.transform.localScale);

                        //tweener = TweenManager.ComponentTween(target.transform, vector3_from, vector3_to, duration, loopMode, ease, curve, ingoreTimeScale, TransformExtensions.OnTweenLocalScale, delay, progress, loopCount);
                        t_local_scale.From = vector3_from;
                        t_local_scale.To = vector3_to;
                    }

                    break;
            }
            

        }

        private void HandleAnimationSpriteRenderer( bool inverse = false, bool fromCurrentProgress = false, bool ingoreTimeScale = true)
        {
            SpriteRenderer spriteRenderer = target.GetComponent<SpriteRenderer>();
            if (spriteRenderer == null) return;

            //Tweener tweener = null; 
            //float progress = 0;

            switch (spriteRendererTweenType)
            {
                case SpriteRendererTweenType.Color:

                    TweenerCore<Color> t_color = InitTweenerColor(spriteRenderer, SpriteRendererExtensions.OnTweenColor);

                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = ColorExtensions.InverseLerp(color_to, color_from, spriteRenderer.color);

                        //tweener = TweenManager.ComponentTween(spriteRenderer, color_to, color_from, duration, loopMode, ease, curve, ingoreTimeScale, SpriteRendererExtensions.OnTweenColor, delay, progress, loopCount);
                        t_color.From = color_to;
                        t_color.To = color_from;
                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = ColorExtensions.InverseLerp(color_from, color_to, spriteRenderer.color);

                        //tweener = TweenManager.ComponentTween(spriteRenderer, color_from, color_to, duration, loopMode, ease, curve, ingoreTimeScale, SpriteRendererExtensions.OnTweenColor, delay, progress, loopCount);

                        t_color.From = color_from;
                        t_color.To = color_to;

                    }

                    break;
                case SpriteRendererTweenType.Fade:


                    TweenerCore<float> t_fade = InitTweenerFloat(spriteRenderer, SpriteRendererExtensions.OnTweenFade);

                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = Mathf.InverseLerp(float_to, float_from, spriteRenderer.color.a);

                        //tweener = TweenManager.ComponentTween(spriteRenderer, float_to, float_from, duration, loopMode, ease, curve, ingoreTimeScale, SpriteRendererExtensions.OnTweenFade, delay, progress, loopCount);
                        t_fade.From = float_to;
                        t_fade.To = float_from;
                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = Mathf.InverseLerp(float_from, float_to, spriteRenderer.color.a);

                        //tweener = TweenManager.ComponentTween(spriteRenderer, float_from, float_to, duration, loopMode, ease, curve, ingoreTimeScale, SpriteRendererExtensions.OnTweenFade, delay, progress, loopCount);

                        t_fade.From = float_from;
                        t_fade.To = float_to;
                    }

                    break;
                case SpriteRendererTweenType.Size:

                    TweenerCore<Vector2> t_size = InitTweenerVector2(spriteRenderer, SpriteRendererExtensions.OnTweenSize);

                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector2Extensions.InverseLerp(vector2_to, vector2_from, spriteRenderer.size);

                        //tweener = TweenManager.ComponentTween(spriteRenderer, vector2_to, vector2_from, duration, loopMode, ease, curve, ingoreTimeScale, SpriteRendererExtensions.OnTweenSize, delay, progress, loopCount);

                        t_size.From = vector2_to;
                        t_size.To = vector2_from;

                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector2Extensions.InverseLerp(vector2_from, vector2_to, spriteRenderer.size);

                        //tweener = TweenManager.ComponentTween(spriteRenderer, vector2_from, vector2_to, duration, loopMode, ease, curve, ingoreTimeScale, SpriteRendererExtensions.OnTweenSize, delay, progress, loopCount);

                        t_size.From = vector2_from;
                        t_size.To = vector2_to;
                    }

                    break;
            }

            //if (tweener != null)
            //    SetTweener(tweener);
        }

        private void HandleAnimationSlider(  bool inverse = false, bool fromCurrentProgress = false, bool ingoreTimeScale = true)
        {
            Slider slider = target.GetComponent<Slider>();
            if (slider == null) return;
             

            switch (sliderTweenType)
            {
                case SliderTweenType.Value:

                    TweenerCore<float> t_value = InitTweenerFloat(slider, SliderExtensions.OnTweenValue);

                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = Mathf.InverseLerp(float_to, float_from, slider.value);

                        //tweener = TweenManager.ComponentTween(slider, float_to, float_from, duration, loopMode, ease, curve, ingoreTimeScale, SliderExtensions.OnTweenValue, delay, progress, loopCount);
                        t_value.From = float_to;
                        t_value.To = float_from;
                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = Mathf.InverseLerp(float_from, float_to, slider.value);

                        //tweener = TweenManager.ComponentTween(slider, float_from, float_to, duration, loopMode, ease, curve, ingoreTimeScale, SliderExtensions.OnTweenValue, delay, progress, loopCount);
                        t_value.From = float_from;
                        t_value.To = float_to;
                    }
                    break;
                case SliderTweenType.NormalizedValue:

                    TweenerCore<float> t_normalized_value = InitTweenerFloat(slider, SliderExtensions.OnTweenNormalizedValue);

                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = Mathf.InverseLerp(float_to, float_from, slider.normalizedValue);

                        //tweener = TweenManager.ComponentTween(slider, float_to, float_from, duration, loopMode, ease, curve, ingoreTimeScale, SliderExtensions.OnTweenNormalizedValue, delay, progress, loopCount);
                        
                        t_normalized_value.From = float_to;
                        t_normalized_value.To = float_from;

                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = Mathf.InverseLerp(float_from, float_to, slider.normalizedValue);

                        //tweener = TweenManager.ComponentTween(slider, float_from, float_to, duration, loopMode, ease, curve, ingoreTimeScale, SliderExtensions.OnTweenNormalizedValue, delay, progress, loopCount);

                        t_normalized_value.From = float_from;
                        t_normalized_value.To = float_to;

                    }
                    break;
            }
             

        }

        private void HandleAnimationScrollRect(  bool inverse = false, bool fromCurrentProgress = false, bool ingoreTimeScale = true)
        {

            ScrollRect scrollRect = target.GetComponent<ScrollRect>();
            if (scrollRect == null) return;

            //Tweener tweener = null; 
            //float progress = 0;

            switch (scrollRectTweenType)
            {
                case ScrollRectTweenType.HorizontalNormalizedPosition:

                    TweenerCore<float> t_hnp = InitTweenerFloat(scrollRect, ScrollRectExtensions.OnTweenHorizontalNormalizedPosition);

                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = Mathf.InverseLerp(float_to, float_from, scrollRect.horizontalNormalizedPosition);

                        //tweener = TweenManager.ComponentTween(scrollRect, float_to, float_from, duration, loopMode, ease, curve, ingoreTimeScale, ScrollRectExtensions.OnTweenHorizontalNormalizedPosition, delay, progress, loopCount);
                        t_hnp.From = float_to;
                        t_hnp.To = float_from;
                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = Mathf.InverseLerp(float_from, float_to, scrollRect.horizontalNormalizedPosition);

                        //tweener = TweenManager.ComponentTween(scrollRect, float_from, float_to, duration, loopMode, ease, curve, ingoreTimeScale, ScrollRectExtensions.OnTweenHorizontalNormalizedPosition, delay, progress, loopCount);
                        t_hnp.From = float_from;
                        t_hnp.To = float_to;

                    }

                    break;
                case ScrollRectTweenType.VerticalNormalizedPosition:


                    TweenerCore<float> t_vnp = InitTweenerFloat(scrollRect, ScrollRectExtensions.OnTweenVerticalNormalizedPosition);
                    
                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = Mathf.InverseLerp(float_to, float_from, scrollRect.verticalNormalizedPosition);

                        //tweener = TweenManager.ComponentTween(scrollRect, float_to, float_from, duration, loopMode, ease, curve, ingoreTimeScale, ScrollRectExtensions.OnTweenVerticalNormalizedPosition, delay, progress, loopCount);

                        t_vnp.From = float_to;
                        t_vnp.To = float_from;
                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = Mathf.InverseLerp(float_from, float_to, scrollRect.verticalNormalizedPosition);

                        //tweener = TweenManager.ComponentTween(scrollRect, float_from, float_to, duration, loopMode, ease, curve, ingoreTimeScale, ScrollRectExtensions.OnTweenVerticalNormalizedPosition, delay, progress, loopCount);

                        t_vnp.From = float_from;
                        t_vnp.To = float_to; 
                    }
                    break;
                case ScrollRectTweenType.NormalizedPosition:

                    TweenerCore<Vector2> t_np = InitTweenerVector2(scrollRect, ScrollRectExtensions.OnTweenNormalizedPosition);

                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector2Extensions.InverseLerp(vector2_to, vector2_from, scrollRect.normalizedPosition);

                        //tweener = TweenManager.ComponentTween(scrollRect, vector2_to, vector2_from, duration, loopMode, ease, curve, ingoreTimeScale, ScrollRectExtensions.OnTweenNormalizedPosition, delay, progress, loopCount);
                        t_np.From = vector2_to;
                        t_np.To = vector2_from;
                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector2Extensions.InverseLerp(vector2_from, vector2_to, scrollRect.normalizedPosition);

                        //tweener = TweenManager.ComponentTween(scrollRect, vector2_from, vector2_to, duration, loopMode, ease, curve, ingoreTimeScale, ScrollRectExtensions.OnTweenNormalizedPosition, delay, progress, loopCount);
                        t_np.From = vector2_from;
                        t_np.To = vector2_to;

                    }
                    break;
            }

            //if (tweener != null)
            //    SetTweener(tweener);

        }

        private void HandleAnimationRectTransfrom(  bool inverse = false, bool fromCurrentProgress = false, bool ingoreTimeScale = true)
        {
            RectTransform rectTransform = target.GetComponent<RectTransform>();
            if (rectTransform == null) return;

            //Tweener tweener = null;

            //float progress = 0;

            switch (rectTransfromTweenType)
            {
                case RectTransfromTweenType.AnchoredPosition:

                    TweenerCore<Vector2> t_ap = InitTweenerVector2(rectTransform, RectTransformExtensions.OnTweenAnchoredPosition);

                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector2Extensions.InverseLerp(vector2_to, vector2_from, rectTransform.anchoredPosition);

                        //tweener = TweenManager.ComponentTween(rectTransform, vector2_to, vector2_from, duration, loopMode, ease, curve, ingoreTimeScale, RectTransformExtensions.OnTweenAnchoredPosition, delay, progress, loopCount);
                        t_ap.From = vector2_to;
                        t_ap.To = vector2_from;
                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector2Extensions.InverseLerp(vector2_from, vector2_to, rectTransform.anchoredPosition);

                        //tweener = TweenManager.ComponentTween(rectTransform, vector2_from, vector2_to, duration, loopMode, ease, curve, ingoreTimeScale, RectTransformExtensions.OnTweenAnchoredPosition, delay, progress, loopCount);
                        t_ap.From = vector2_from;
                        t_ap.To = vector2_to;

                    }
                    break;
                case RectTransfromTweenType.AnchoredPosition3D:

                    TweenerCore<Vector3> t_ap_3d = InitTweenerVector3(rectTransform, RectTransformExtensions.OnTweenAnchoredPosition3D);

                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector3Extensions.InverseLerp(vector3_to, vector3_from, rectTransform.anchoredPosition3D);

                        //tweener = TweenManager.ComponentTween(rectTransform, vector3_to, vector3_from, duration, loopMode, ease, curve, ingoreTimeScale, RectTransformExtensions.OnTweenAnchoredPosition3D, delay, progress, loopCount);
                        t_ap_3d.From = vector3_to;
                        t_ap_3d.To = vector3_from;
                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector3Extensions.InverseLerp(vector3_from, vector3_to, rectTransform.anchoredPosition3D);

                        //tweener = TweenManager.ComponentTween(rectTransform, vector3_from, vector3_to, duration, loopMode, ease, curve, ingoreTimeScale, RectTransformExtensions.OnTweenAnchoredPosition3D, delay, progress, loopCount);

                        t_ap_3d.From = vector3_from;
                        t_ap_3d.To = vector3_to;

                    }
                    break;
                case RectTransfromTweenType.AnchorMin:

                    TweenerCore<Vector2> t_am = InitTweenerVector2(rectTransform, RectTransformExtensions.OnTweenAnchorMin);

                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector2Extensions.InverseLerp(vector2_to, vector2_from, rectTransform.anchorMin);

                        //tweener = TweenManager.ComponentTween(rectTransform, vector2_to, vector2_from, duration, loopMode, ease, curve, ingoreTimeScale, RectTransformExtensions.OnTweenAnchorMin, delay, progress, loopCount);
                        t_am.From = vector2_to;
                        t_am.To = vector2_from;
                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector2Extensions.InverseLerp(vector2_from, vector2_to, rectTransform.anchorMin);

                        //tweener = TweenManager.ComponentTween(rectTransform, vector2_from, vector2_to, duration, loopMode, ease, curve, ingoreTimeScale, RectTransformExtensions.OnTweenAnchorMin, delay, progress, loopCount);
                        t_am.From = vector2_from;
                        t_am.To = vector2_to;
                    }
                    break;
                case RectTransfromTweenType.AnchorMax:

                    TweenerCore<Vector2> t_anchor_max = InitTweenerVector2(rectTransform, RectTransformExtensions.OnTweenAnchorMax);

                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector2Extensions.InverseLerp(vector2_to, vector2_from, rectTransform.anchorMax);

                        //tweener = TweenManager.ComponentTween(rectTransform, vector2_to, vector2_from, duration, loopMode, ease, curve, ingoreTimeScale, RectTransformExtensions.OnTweenAnchorMax, delay, progress, loopCount);
                        t_anchor_max.From = vector2_to;
                        t_anchor_max.To = vector2_from;
                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector2Extensions.InverseLerp(vector2_from, vector2_to, rectTransform.anchorMax);

                        //tweener = TweenManager.ComponentTween(rectTransform, vector2_from, vector2_to, duration, loopMode, ease, curve, ingoreTimeScale, RectTransformExtensions.OnTweenAnchorMax, delay, progress, loopCount);

                        t_anchor_max.From = vector2_from;
                        t_anchor_max.To = vector2_to;

                    }
                    break;
                case RectTransfromTweenType.OffsetMin:

                    TweenerCore<Vector2> t_offset_min = InitTweenerVector2(rectTransform, RectTransformExtensions.OnTweenOffsetMin);

                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector2Extensions.InverseLerp(vector2_to, vector2_from, rectTransform.offsetMin);

                        //tweener = TweenManager.ComponentTween(rectTransform, vector2_to, vector2_from, duration, loopMode, ease, curve, ingoreTimeScale, RectTransformExtensions.OnTweenOffsetMin, delay, progress, loopCount);
                        t_offset_min.From = vector2_to;
                        t_offset_min.To = vector2_from;
                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector2Extensions.InverseLerp(vector2_from, vector2_to, rectTransform.offsetMin);

                        //tweener = TweenManager.ComponentTween(rectTransform, vector2_from, vector2_to, duration, loopMode, ease, curve, ingoreTimeScale, RectTransformExtensions.OnTweenOffsetMin, delay, progress, loopCount);

                        t_offset_min.From = vector2_from;
                        t_offset_min.To = vector2_to;

                    }
                    break;
                case RectTransfromTweenType.OffsetMax:

                    TweenerCore<Vector2> t_offset_max = InitTweenerVector2(rectTransform, RectTransformExtensions.OnTweenOffsetMax);

                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector2Extensions.InverseLerp(vector2_to, vector2_from, rectTransform.offsetMax);

                        //tweener = TweenManager.ComponentTween(rectTransform, vector2_to, vector2_from, duration, loopMode, ease, curve, ingoreTimeScale, RectTransformExtensions.OnTweenOffsetMax, delay, progress, loopCount);
                        t_offset_max.From = vector2_to;
                        t_offset_max.To = vector2_from;
                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector2Extensions.InverseLerp(vector2_from, vector2_to, rectTransform.offsetMax);

                        //tweener = TweenManager.ComponentTween(rectTransform, vector2_from, vector2_to, duration, loopMode, ease, curve, ingoreTimeScale, RectTransformExtensions.OnTweenOffsetMax, delay, progress, loopCount);

                        t_offset_max.From = vector2_from;
                        t_offset_max.To = vector2_to;

                    }
                    break;
                case RectTransfromTweenType.Pivot:

                    TweenerCore<Vector2> t_pivot = InitTweenerVector2(rectTransform, RectTransformExtensions.OnTweenPivot);

                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector2Extensions.InverseLerp(vector2_to, vector2_from, rectTransform.pivot);

                        //tweener = TweenManager.ComponentTween(rectTransform, vector2_to, vector2_from, duration, loopMode, ease, curve, ingoreTimeScale, RectTransformExtensions.OnTweenPivot, delay, progress, loopCount);
                        t_pivot.From = vector2_to;
                        t_pivot.To = vector2_from; 
                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector2Extensions.InverseLerp(vector2_from, vector2_to, rectTransform.pivot);

                        //tweener = TweenManager.ComponentTween(rectTransform, vector2_from, vector2_to, duration, loopMode, ease, curve, ingoreTimeScale, RectTransformExtensions.OnTweenPivot, delay, progress, loopCount);

                        t_pivot.From = vector2_from;
                        t_pivot.To = vector2_to;

                    }
                    break;
                case RectTransfromTweenType.SizeDelta:

                    TweenerCore<Vector2> t_size_delta = InitTweenerVector2(rectTransform, RectTransformExtensions.OnTweenSizeDelta);

                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector2Extensions.InverseLerp(vector2_to, vector2_from, rectTransform.sizeDelta);

                        //tweener = TweenManager.ComponentTween(rectTransform, vector2_to, vector2_from, duration, loopMode, ease, curve, ingoreTimeScale, RectTransformExtensions.OnTweenSizeDelta, delay, progress, loopCount);

                        t_size_delta.From = vector2_to;
                        t_size_delta.To = vector2_from;

                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = Vector2Extensions.InverseLerp(vector2_from, vector2_to, rectTransform.sizeDelta);

                        //tweener = TweenManager.ComponentTween(rectTransform, vector2_from, vector2_to, duration, loopMode, ease, curve, ingoreTimeScale, RectTransformExtensions.OnTweenSizeDelta, delay, progress, loopCount);


                        t_size_delta.From = vector2_from;
                        t_size_delta.To = vector2_to;

                    }
                    break;
            }


            //if (tweener != null)
            //    SetTweener(tweener);
        }

        private void HandleAnimationImage(  bool inverse = false, bool fromCurrentProgress = false, bool ingoreTimeScale = true)
        {
            Image image = target.GetComponent<Image>();
            if (image == null) return;
             


            switch (imageTweenType)
            {
                case ImageTweenType.FillAmount:

                    TweenerCore<float> t_fill_amount = InitTweenerFloat(image, ImageExtensions.OnTweenFillAmount);

                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = Mathf.InverseLerp(float_to, float_from, image.fillAmount);

                        //tweener = TweenManager.ComponentTween(image, float_to, float_from, duration, loopMode, ease, curve, ingoreTimeScale, ImageExtensions.OnTweenFillAmount, delay, progress, loopCount);
                        t_fill_amount.From = float_to;
                        t_fill_amount.To = float_from;
                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = Mathf.InverseLerp(float_from, float_to, image.fillAmount);

                        //tweener = TweenManager.ComponentTween(image, float_from, float_to, duration, loopMode, ease, curve, ingoreTimeScale, ImageExtensions.OnTweenFillAmount, delay, progress, loopCount);

                        t_fill_amount.From = float_from;
                        t_fill_amount.To = float_to;

                    }
                    break;
                case ImageTweenType.Color: 
                    graphicTweenType = GraphicTweenType.Color;
                    HandleAnimationGraphic(  inverse, fromCurrentProgress);
                    break;
                case ImageTweenType.Fade:
                    graphicTweenType = GraphicTweenType.Fade;
                    HandleAnimationGraphic( inverse, fromCurrentProgress);
                    break;

            }

            //if (tweener != null)
            //    SetTweener(tweener);
        }

        private void HandleAnimationGraphic(  bool inverse = false, bool fromCurrentProgress = false, bool ingoreTimeScale = true)
        {
            Graphic graphic = target.GetComponent<Graphic>();
            if (graphic == null) return;

            //Tweener tweener = null; 
            //float progress = 0;

            switch (graphicTweenType)
            {
                case GraphicTweenType.Color:

                    TweenerCore<Color> t_color = InitTweenerColor(graphic, GraphicExtensions.OnTweenColor);

                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = ColorExtensions.InverseLerp(color_to, color_from, graphic.color);
                        //tweener = TweenManager.ComponentTween(graphic, color_to, color_from, duration, loopMode, ease, curve, ingoreTimeScale, GraphicExtensions.OnTweenColor, delay, progress, loopCount);
                        t_color.From = color_to;
                        t_color.To = color_from;
                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = ColorExtensions.InverseLerp(color_from, color_to, graphic.color);

                        //tweener = TweenManager.ComponentTween(graphic, color_from, color_to, duration, loopMode, ease, curve, ingoreTimeScale, GraphicExtensions.OnTweenColor, delay, progress, loopCount);

                        t_color.From = color_from;
                        t_color.To = color_to;
                    }
                    break;
                case GraphicTweenType.Fade:

                    TweenerCore<float> t_fade = InitTweenerFloat(graphic, GraphicExtensions.OnTweenFade);

                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = Mathf.InverseLerp(float_to, float_from, graphic.color.a);

                        //tweener = TweenManager.ComponentTween(graphic, float_to, float_from, duration, loopMode, ease, curve, ingoreTimeScale, GraphicExtensions.OnTweenFade, delay, progress, loopCount);
                        t_fade.From = float_to;
                        t_fade.To = float_from;
                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = Mathf.InverseLerp(float_from, float_to, graphic.color.a);

                        //tweener = TweenManager.ComponentTween(graphic, float_from, float_to, duration, loopMode, ease, curve, ingoreTimeScale, GraphicExtensions.OnTweenFade, delay, progress, loopCount);
                        t_fade.From = float_from;
                        t_fade.To = float_to;
                    }
                    break;
            }

            //if (tweener != null)
            //    SetTweener(tweener);
        }

        private void HandleAnimationCanvasGroup(  bool inverse = false, bool fromCurrentProgress = false, bool ingoreTimeScale = true)
        {
            CanvasGroup canvasGroup = target.GetComponent<CanvasGroup>();
            if (canvasGroup == null) return;

            //Tweener tweener = null;

            //float progress = 0;

            switch (canvasGroupTweenType)
            {
                case CanvasGroupTweenType.Fade:

                    TweenerCore<float> t_fade = InitTweenerFloat(canvasGroup, CanvasGroupExtensions.OnTweenFade);

                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = Mathf.InverseLerp(float_to, float_from, canvasGroup.alpha);

                        //tweener = TweenManager.ComponentTween(canvasGroup, float_to, float_from, duration, loopMode, ease, curve, ingoreTimeScale, CanvasGroupExtensions.OnTweenFade, delay, progress, loopCount);
                        t_fade.From = float_to;
                        t_fade.To = float_from; 
                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = Mathf.InverseLerp(float_from, float_to, canvasGroup.alpha);

                        //tweener = TweenManager.ComponentTween(canvasGroup, float_from, float_to, duration, loopMode, ease, curve, ingoreTimeScale, CanvasGroupExtensions.OnTweenFade, delay, progress, loopCount);

                        t_fade.From = float_from;
                        t_fade.To = float_to;
                    }
                    break;
            }

            //if (tweener != null)
            //    SetTweener(tweener);
        }

        private void HandleAnimationAnimator( bool inverse = false, bool fromCurrentProgress = false, bool ingoreTimeScale = true)
        {
            Animator animator = target.GetComponent<Animator>();
            if (animator == null) return;
             

            switch (animatorTweenType)
            {
                case AnimatorTweenType.LayerWeight:
                     
                    int layerIndex = animator.GetLayerIndex(layerName);

                    Action<TweenerCore<float>> callback = (TweenerCore<float> t) =>
                    {
                        animator.SetLayerWeight(layerIndex, t.Value);
                    };

                    TweenerCore<float> t_layer_weight = InitTweenerFloat(animator, callback);

                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = Mathf.InverseLerp(float_to, float_from, layerIndex);

                        //tweener = TweenManager.ComponentTween(animator, float_to, float_from, duration, loopMode, ease, curve, ingoreTimeScale, callback, delay, progress, loopCount);
                        t_layer_weight.From = float_to;
                        t_layer_weight.To = float_from;
                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = Mathf.InverseLerp(float_from, float_to, layerIndex);

                        //tweener = TweenManager.ComponentTween(animator, float_from, float_to, duration, loopMode, ease, curve, ingoreTimeScale, callback, delay, progress, loopCount);

                        t_layer_weight.From = float_from;
                        t_layer_weight.To = float_to;

                    }
                    break;
            }
             
        }

        private void HandleAnimationText( bool inverse = false, bool fromCurrentProgress = false, bool ingoreTimeScale = true)
        {
            Text text = target.GetComponent<Text>();

            if (text == null) return;

            //Tweener tweener = null;

            switch (textTweenType)
            {
                case TextTweenType.Text:

                    Action<TweenerCore<float>> callback = (TweenerCore<float> t) =>
                    {
                        text.text = str_value.Substring(0, (int)Mathf.Lerp(0, str_value.Length, t.Value));
                    };

                    TweenerCore<float> t_text = InitTweenerFloat(text, callback);

                    if (inverse)
                    { 
                        t_text.From = 1;
                        t_text.To = 0;
                    }
                    else {
                        t_text.From = 0;
                        t_text.To = 1;
                    }

                    currentProgress = 0;

                    
                    break;
                case TextTweenType.Color:
                    graphicTweenType = GraphicTweenType.Color;
                    HandleAnimationGraphic(  inverse, fromCurrentProgress);
                    break;

                case TextTweenType.Fade:
                    graphicTweenType = GraphicTweenType.Fade;
                    HandleAnimationGraphic(  inverse, fromCurrentProgress);
                    break;
            }

            //if (tweener != null)
            //    SetTweener(tweener);
        }


        private void HandleAnimationTextMesh(  bool inverse = false, bool fromCurrentProgress = false, bool ingoreTimeScale = true)
        {
            TextMesh text = target.GetComponent<TextMesh>();

            if (text == null) return;
              
            switch (textTweenType)
            {
                case TextTweenType.Text:

                    Action<TweenerCore<float>> callback = (TweenerCore<float> t) =>
                    {
                        text.text = str_value.Substring(0, (int)Mathf.Lerp(0, str_value.Length, t.Value));
                    };

                    TweenerCore<float> t_text = InitTweenerFloat(text, callback);

                    if (inverse)
                    {
                        t_text.From = 1;
                        t_text.To = 0;
                    }
                    else
                    {
                        t_text.From = 0;
                        t_text.To = 1;
                    }

                    currentProgress = 0;
                     
                    break;

                case TextTweenType.Color:

                    TweenerCore<Color> t_color = InitTweenerColor(text, TextExtensions.OnTweenColor);

                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = ColorExtensions.InverseLerp(color_to, color_from, text.color);
                        //tweener = TweenManager.ComponentTween(text, color_to, color_from, duration, loopMode, ease, curve, ingoreTimeScale, TextExtensions.OnTweenColor, delay, progress, loopCount);
                        t_color.From = color_to;
                        t_color.To = color_from;
                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = ColorExtensions.InverseLerp(color_from, color_to, text.color);

                        //tweener = TweenManager.ComponentTween(text, color_from, color_to, duration, loopMode, ease, curve, ingoreTimeScale, TextExtensions.OnTweenColor, delay, progress, loopCount);
                        
                        t_color.From = color_from;
                        t_color.To = color_to; 
                    }
                    break;
                case TextTweenType.Fade:

                    TweenerCore<float> t_fade = InitTweenerFloat(text, TextExtensions.OnTweenFade);

                    if (inverse)
                    {
                        if (fromCurrentProgress)
                            currentProgress = Mathf.InverseLerp(float_to, float_from, text.color.a);

                        //tweener = TweenManager.ComponentTween(text, float_to, float_from, duration, loopMode, ease, curve, ingoreTimeScale, TextExtensions.OnTweenFade, delay, progress, loopCount);
                        t_fade.From = float_to;
                        t_fade.To = float_from;
                    }
                    else
                    {
                        if (fromCurrentProgress)
                            currentProgress = Mathf.InverseLerp(float_from, float_to, text.color.a);

                        //tweener = TweenManager.ComponentTween(text, float_from, float_to, duration, loopMode, ease, curve, ingoreTimeScale, TextExtensions.OnTweenFade, delay, progress, loopCount);

                        t_fade.From = float_from;
                        t_fade.To = float_to;

                    }
                    break;
            }

            //if (tweener != null)
            //    SetTweener(tweener);
        }

#if TWEENSYSTEM_ENABLE_TEXTMESHPRO

        private void HandleAnimationTextMeshPro(  bool inverse = false, bool fromCurrentProgress = false, bool ingoreTimeScale = true)
        {
            TextMeshPro text = target.GetComponent<TextMeshPro>();

            if (text == null) return;

            //Tweener tweener = null;

            switch (textTweenType)
            {
                case TextTweenType.Text:

                    Action<TweenerCore<float>> callback = (TweenerCore<float> t) =>
                    {
                        text.text = str_value.Substring(0, (int)Mathf.Lerp(0, str_value.Length, t.Value));
                    };

                    TweenerCore<float> t_text = InitTweenerFloat(text, callback);

                    if (inverse)
                    {
                        t_text.From = 1;
                        t_text.To = 0;
                    }
                    else
                    {
                        t_text.From = 0;
                        t_text.To = 1;
                    }

                    currentProgress = 0;

                    //tweener = text.TweenText(str_value, duration, loopMode, ease, curve, ingoreTimeScale, delay, loopCount);
                    break;
                case TextTweenType.Color:
                    graphicTweenType = GraphicTweenType.Color;
                    HandleAnimationGraphic( inverse, fromCurrentProgress);
                    break;

                case TextTweenType.Fade:
                    graphicTweenType = GraphicTweenType.Fade;
                    HandleAnimationGraphic(  inverse, fromCurrentProgress);
                    break;
            }
             
        }

        private void HandleAnimationTextMeshProUGUI( bool inverse = false, bool fromCurrentProgress = false, bool ingoreTimeScale = true)
        {
            TextMeshProUGUI text = target.GetComponent<TextMeshProUGUI>();

            if (text == null) return; 
            //Tweener tweener = null;

            switch (textTweenType)
            {
                case TextTweenType.Text:

                    Action<TweenerCore<float>> callback = (TweenerCore<float> t) =>
                    {
                        text.text = str_value.Substring(0, (int)Mathf.Lerp(0, str_value.Length, t.Value));
                    };

                    TweenerCore<float> t_text = InitTweenerFloat(text, callback);

                    if (inverse)
                    {
                        t_text.From = 1;
                        t_text.To = 0;
                    }
                    else
                    {
                        t_text.From = 0;
                        t_text.To = 1;
                    }

                    currentProgress = 0;

                    //tweener = text.TweenText(str_value, duration, loopMode, ease, curve, ingoreTimeScale, delay, loopCount);
                    break;
                case TextTweenType.Color:
                    graphicTweenType = GraphicTweenType.Color;
                    HandleAnimationGraphic(  inverse, fromCurrentProgress);
                    break;

                case TextTweenType.Fade:
                    graphicTweenType = GraphicTweenType.Fade;
                    HandleAnimationGraphic(  inverse, fromCurrentProgress);
                    break;
            }

            //if (tweener != null)
            //    SetTweener(tweener);
        }

#endif

        private void ClearTweener() 
        {
            if (tweener == null) return;

            tweener.onTween = null;
            tweener.onKill = null;
            tweener.RemoveAllCompleteEvent();
            tweener = null;
        }

        private void RegisterTweener() 
        {

            if (tweener == null) return;

            tweener.onTween -= OnTween;
            tweener.onTween += OnTween;

            tweener.RemoveCompleteEvent(OnComplete);
            tweener.AddCompleteEvent(OnComplete);

            tweener.onKill -= OnKill;
            tweener.onKill += OnKill;
        }

        private TweenerCore<float> InitTweenerFloat(Component component,Action<TweenerCore<float>> onValueChange)
        {
            
            if (tweener != null && !(tweener is TweenerCore<float>)) 
            {
                ClearTweener();
            }

            if (tweener == null) { 
                tweener = TweenManager.TweenFloat(component);

                RegisterTweener();
            }

            TweenerCore<float> t = tweener as TweenerCore<float>;

            t.onValueChange = null;
            t.onValueChange += onValueChange;

            return t;
        }


        private TweenerCore<Vector2> InitTweenerVector2(Component component, Action<TweenerCore<Vector2>> onValueChange)
        {

            if (tweener != null && !(tweener is TweenerCore<Vector2>))
            {
                ClearTweener();
            }

            if (tweener == null)
            {
                tweener = TweenManager.TweenVector2(component);

                RegisterTweener();
            }

            TweenerCore<Vector2> t = tweener as TweenerCore<Vector2>;

            t.onValueChange = null;
            t.onValueChange += onValueChange;

            return t;
        }

        private TweenerCore<Vector3> InitTweenerVector3(Component component, Action<TweenerCore<Vector3>> onValueChange)
        {

            if (tweener != null && !(tweener is TweenerCore<Vector3>))
            {
                ClearTweener();
            }

            if (tweener == null)
            {
                tweener = TweenManager.TweenVector3(component); 
                RegisterTweener();
            }

            TweenerCore<Vector3> t = tweener as TweenerCore<Vector3>;

            t.onValueChange = null;
            t.onValueChange += onValueChange;

            return t;
        }

        private TweenerCore<Quaternion> InitTweenerQuaternion(Component component, Action<TweenerCore<Quaternion>> onValueChange)
        {

            if (tweener != null && !(tweener is TweenerCore<Quaternion>))
            {
                ClearTweener();
            }

            if (tweener == null)
            {
                tweener = TweenManager.TweenQuaternion(component);
                RegisterTweener();
            }

            TweenerCore<Quaternion> t = tweener as TweenerCore<Quaternion>;

            t.onValueChange = null;
            t.onValueChange += onValueChange;

            return t;
        }


        private TweenerCore<Color> InitTweenerColor(Component component, Action<TweenerCore<Color>> onValueChange)
        {

            if (tweener != null && !(tweener is TweenerCore<Color>))
            {
                ClearTweener();
            }

            if (tweener == null)
            {
                tweener = TweenManager.TweenColor(component);
                RegisterTweener();
            }

            TweenerCore<Color> t = tweener as TweenerCore<Color>;

            t.onValueChange = null;
            t.onValueChange += onValueChange;

            return t;
        }


        #endregion


    }

    /// <summary>
    /// 渐变动画组件
    /// </summary>
    [HelpURL("https://gitee.com/xianfengkeji/xfgameframework.tween-system/blob/master/Documentation~/ClassApi/TweenAnimation.md")]
    public class TweenAnimation : MonoBehaviour
    {
        #region 字段  
 
        [SerializeField]
        [Tooltip("所有动画数据")]
        private List<AnimationData> animationDatas;
         
        [SerializeField]
        [Tooltip("是否自动播放")]
        [Header("是否自动播放")]
        private bool playOnAwake = true;
         
        [SerializeField]
        [Tooltip("是否从当前的进度开始执行动画")]
        [Header("是否从当前的进度开始执行动画")]
        private bool fromCurrentProgress = false;
 
        [SerializeField]
        [Tooltip("是否忽略时间缩放,默认:true!")] // 因为大部分通过该组件控制的动画应该是都是UI, 所以需要忽略时间缩放
        [Header("是否忽略时间缩放,默认:true!")]
        private bool ingoreTimeScale = true;

        [SerializeField]
        [Tooltip("顺序播放动画(已过时,请使用组件:TweenAnimationSequence实现顺序播放动画功能!)")]
        [Header("顺序播放动画(已过时,请使用组件:TweenAnimationSequence实现顺序播放动画功能!)")]
        [Obsolete("已过时,请使用组件:TweenAnimationSequence实现顺序播放动画功能!")]
        private bool sequence = false;

        [SerializeField]
        [Tooltip("顺序播放动画 循环模式")]
        [Header("顺序播放动画 循环模式")]
        private LoopMode sequenceLoopMode;

        [SerializeField]
        [Tooltip("顺序播放动画 循环次数(<=0表示一直循环)")]
        [Header("顺序播放动画 循环次数(<=0表示一直循环)")]
        private int sequenceLoopCount = -1;

     
        [Tooltip("序列动画播放结束事件")]
        [Header("序列动画播放结束事件")]
        public UnityEvent onSequenceCompleted;


        private TweenerSequence tweenerSequence;

        #endregion

        #region 属性

        /// <summary>
        /// 是否忽略时间缩放,默认:true
        /// </summary>
        public bool IngoreTimeScale
        {
            get 
            {
                return ingoreTimeScale;
            }
            set {
                ingoreTimeScale = value;
            }
        }

        /// <summary>
        /// 所有动画数据
        /// </summary>
        public List<AnimationData> AnimationDatas => animationDatas;

        /// <summary>
        /// 当前动画是否反着播(true:反 false:正)
        /// </summary>
        public bool Inverse { get;private set; }

        /// <summary>
        /// 是否正在播放动画
        /// </summary>
        public bool IsPlaying {
            get {

                foreach (var item in animationDatas)
                {
                    if (item.tweener == null) continue;

                    if(item.tweener.isPlaying) return true;

                }

                return false;
            }
        }

        #endregion



        #region 事件 

        /// <summary>
        /// 播放动画时触发
        /// </summary>
        [Tooltip("播放动画时触发")]
        public UnityEvent onPlay;

        /// <summary>
        /// 暂停动画时触发
        /// </summary>
        [Tooltip("暂停动画时触发")]
        public AnimationBoolEvent onPause;

        #endregion


        #region 生命周期

        private void OnEnable()
        {  
            if(playOnAwake) Play(); 
        }

        private void OnDisable()
        { 
            // 结束动画
            Stop(); 
        }


        #endregion

        #region 方法

        /// <summary>
        /// 播放动画
        /// </summary>
        /// <param name="inverse">是否反向播</param>
        public void Play(bool inverse = false) 
        {
            Stop();

            onPlay?.Invoke();

            // 开始动画 
            foreach (var data in animationDatas)
            {
               data.HandleAnimationData(inverse,fromCurrentProgress,ingoreTimeScale);

                if (data.tweener != null)  
                    data.tweener.Play(fromCurrentProgress ? data.currentProgress : 0);  
            }
              
#pragma warning disable CS0618 // 类型或成员已过时
            if (sequence) 
            {
                if (tweenerSequence == null) 
                { 
                    tweenerSequence = new TweenerSequence();
                    tweenerSequence.AddCompleteEvent(OnSequenceComplete);
                }

                tweenerSequence.Clear();

                if (!inverse)
                {
                    for (int i = 0; i < animationDatas.Count; i++)
                    {
                        if (animationDatas[i].target == null)
                        {
                            tweenerSequence.AppendInterval(animationDatas[i].duration);
                        }
                        else {  
                            tweenerSequence.Append(animationDatas[i].tweener);
                        } 
                    }
                }
                else 
                {
                    for (int i = animationDatas.Count - 1; i  >= 0; i--)
                    { 
                        if (animationDatas[i].target == null)
                        {
                            tweenerSequence.AppendInterval(animationDatas[i].duration);
                        }
                        else
                        {
                            tweenerSequence.Append(animationDatas[i].tweener);
                        } 
                    }
                }

                tweenerSequence.LoopMode = sequenceLoopMode;
                tweenerSequence.LoopCount = sequenceLoopCount;

                tweenerSequence.Play(); 

            }
#pragma warning restore CS0618 // 类型或成员已过时

        }

        /// <summary>
        /// 暂停
        /// </summary>
        /// <param name="pause">true:暂停 false:取消暂停</param>
        public void Pause(bool pause) 
        {
            // 序列动画
#pragma warning disable CS0618 // 类型或成员已过时
            if (sequence && tweenerSequence != null)
            {
                tweenerSequence.Pause(pause);
            }
#pragma warning restore CS0618 // 类型或成员已过时

            if (animationDatas == null || animationDatas.Count == 0)
                return;

            onPause?.Invoke(pause);

            foreach (var item in animationDatas)
            {
                if (item.tweener == null) continue;
                item.tweener.Pause(pause); 
            }


           
        }

        /// <summary>
        /// 停止动画
        /// </summary>
        public void Stop() 
        {
            // 序列动画
#pragma warning disable CS0618 // 类型或成员已过时
            if (sequence && tweenerSequence != null) 
            {
                tweenerSequence.Kill();
            }
#pragma warning restore CS0618 // 类型或成员已过时

            if (animationDatas == null || animationDatas.Count == 0)
                return;

            foreach (var item in animationDatas) 
            {
                if(item.tweener == null) continue;
                item.tweener.Kill();
                //item.SetTweener(null);
            } 
        }
         
  
        

      

        #endregion


        private void OnSequenceComplete(TweenerSequence sequence) {
            onSequenceCompleted?.Invoke();
        }

    }

}

